package com.asr.plugin_asr

import android.Manifest
import android.annotation.SuppressLint
import android.content.Context
import android.net.ConnectivityManager
import android.net.NetworkCapabilities
import androidx.annotation.RequiresPermission
import com.iflytek.sparkchain.core.SparkChain
import com.iflytek.sparkchain.core.SparkChainConfig

/**
 * ASR SDK 封装类，用于集成讯飞语音识别和语音合成功能。
 *
 * @author linxiongjun
 * @date 2025-05-29
 */
@SuppressLint("StaticFieldLeak")
object ASRSdk  {
    // 日志标签
    const val TAG = "ASRSdkLog"

    // SDK 配置信息
    private lateinit var appId: String
    private lateinit var apiKey: String
    private lateinit var apiSecret: String
    private lateinit var context: Context

    // 语音合成和识别模块
    private val speechSynthesis = SpeechSynthesis()
    private val speechRecognition = SpeechRecognition()
    private val speechPersonSynthesis = SpeechPersonSynthesis()

    /**
     * 设置 ASR SDK 上下文对象。
     *
     * @param context 上下文对象
     */
    fun setContext(context: Context) {
        this.context = context;
    }

    /**
     * 初始化 ASR SDK。
     *
     * @param appId 讯飞开放平台应用ID
     * @param apiKey 讯飞开放平台API Key
     * @param apiSecret 讯飞开放平台API Secret
     * @return 初始化结果，0表示成功，非0表示失败
     */
    fun init(appId: String, apiKey: String, apiSecret: String): Int {
        this.appId = appId
        this.apiKey = apiKey
        this.apiSecret = apiSecret
        return initSparkChain()
    }

    /**
     * 初始化讯飞SDK。
     *
     * @return 初始化结果，0表示成功，非0表示失败
     */
    private fun initSparkChain(): Int {
        // 构建 SparkChain 配置
        val sparkChainConfig = SparkChainConfig
            .builder()
            .appID(appId)
            .apiKey(apiKey)
            .apiSecret(apiSecret)
            .logLevel(666)
        val ret = SparkChain.getInst().init(this.context, sparkChainConfig)
        return ret;
    }


    /**
     * 开始语音识别监听。
     *
     * @param asrListenerResultCallback 语音识别结果的回调函数
     * @return 启动结果，0表示成功，非0表示失败
     */
    fun startAsrListener(language: String, asrListenerResultCallback: (result: String) -> Unit, asrListenerProcessCallback: (result: String) -> Unit): Int {
        return speechRecognition.startAsrListener (
            language,
            { result -> asrListenerResultCallback(result) },
            { result -> asrListenerProcessCallback(result) }
        )
    }

    /**
     * 停止语音识别监听。
     */
    fun stopAsrListener() {
        speechRecognition.stopAsrListener()
    }

    /**
     * 开始在线语音合成。
     *
     * @param text 需要合成的文本
     * @return 合成结果，0表示成功，非0表示失败
     */
    fun startOnlineTTS(text: String): Int {
        return speechSynthesis.startOnlineTTS(text)
    }
    /**
     * 结束在线语音合成。
     *
     * @return 合成结果，0表示成功，非0表示失败
     */
    fun stopOnlineTTS(): Int {
        speechSynthesis.release()
        return 0
    }

    /**
     * 开始拟人语音合成。
     *
     * @param text 需要合成的文本
     * @return 合成结果，0表示成功，非0表示失败
     */
    fun startPersonTTS(text: String, ttsEndCallback: (result: Int) -> Unit): Int {
        return speechPersonSynthesis.startPersonTTS(text, ttsEndCallback)
    }

    /**
     * 开始流式拟人语音合成。
     *
     * @param text 需要合成的文本
     * @param status 合成的状态
     * @return 合成结果，0表示成功，非0表示失败
     */
    fun startFlowPersonTTS(text: String, status: Int, ttsEndCallback: (result: Int) -> Unit): Int {
        return speechPersonSynthesis.startFlowPersonTTS(text, status, ttsEndCallback)
    }

    /**
     * 结束拟人语音合成。
     *
     * @return 合成结果，0表示成功，非0表示失败
     */
    fun stopPersonTTS(): Int {
        speechPersonSynthesis.release()
        return 0
    }

    /**
     * 判断当前设备是否已连接网络（包含WiFi、蜂窝网络等）
     *
     * @return true 表示已连接网络，false 表示未连接
     */
    @RequiresPermission(Manifest.permission.ACCESS_NETWORK_STATE)
    fun isNetworkConnected(): Boolean {
        val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        val network = connectivityManager.activeNetwork ?: return false
        val capabilities = connectivityManager.getNetworkCapabilities(network) ?: return false
        return capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
    }
}

